package com.qsw.qswcommonlib.util;

import android.graphics.Bitmap;
import android.text.TextUtils;
import android.util.Base64;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
 * 数据转换相关工具
 */
public class CommonTransitionUtil {
    private CommonTransitionUtil() {
    }

    /**
     * 获取String的MD5值，16位，默认采用UTF-8
     *
     * @param str 字符串
     * @return 该字符串的MD5值
     */
    public static String getMD516(String str) throws NoSuchAlgorithmException, UnsupportedEncodingException {
        return getMD516(str, StandardCharsets.UTF_8);
    }

    /**
     * 获取String的MD5值，16位
     *
     * @param str     字符串
     * @param charset 编码格式
     * @return 该字符串的MD5值
     */
    public static String getMD516(String str, Charset charset) throws NoSuchAlgorithmException, UnsupportedEncodingException {
        return getMD516(str.getBytes(charset));
    }

    /**
     * 获取byte数组的MD5值，16位
     *
     * @param strArray byte数组
     * @return 该字符串的MD5值
     */
    public static String getMD516(byte[] strArray) throws NoSuchAlgorithmException {
        return getMD516FromMD532(getMD5(strArray));
    }

    /**
     * 获取文件的MD5，16位
     *
     * @param file 文件
     * @return 文件的MD5
     * @throws NoSuchAlgorithmException 异常
     * @throws IOException              异常
     */
    public static String getMD516(File file) throws NoSuchAlgorithmException, IOException {
        return getMD516FromMD532(getMD5(file));
    }

    /**
     * 获取MD5，16位
     *
     * @param md532 32位MD5
     * @return 文件的MD5
     */
    public static String getMD516FromMD532(String md532) {
        if (TextUtils.isEmpty(md532) || !(md532.length() == 32)) {
            return md532;
        }
        return md532.substring(8, 24);
    }

    /**
     * 获取String的MD5值，32位，默认采用UTF-8
     *
     * @param str 字符串
     * @return 该字符串的MD5值
     */
    public static String getMD5(String str) throws NoSuchAlgorithmException, UnsupportedEncodingException {
        return getMD5(str, StandardCharsets.UTF_8);
    }

    /**
     * 获取String的MD5值，32位
     *
     * @param str     字符串
     * @param charset 编码格式
     * @return 该字符串的MD5值
     */
    public static String getMD5(String str, Charset charset) throws NoSuchAlgorithmException, UnsupportedEncodingException {
        return getMD5(str.getBytes(charset));
    }

    /**
     * 获取byte数组的MD5值，32位
     *
     * @param strArray byte数组
     * @return 该字符串的MD5值
     */
    public static String getMD5(byte[] strArray) throws NoSuchAlgorithmException {
        //获取MessageDigest对象，参数为MD5字符串，表示这是一个MD5算法（其他还有 SHA1 算法等）：
        MessageDigest md5 = MessageDigest.getInstance("MD5");
        //update(byte[])方法，输入原数据
        //类似StringBuilder对象的append()方法，追加模式，属于一个累计更改的过程
        md5.update(strArray);
        //digest()被调用后,MessageDigest对象就被重置，即不能连续再次调用该方法计算原数据的MD5值。可以手动调用reset()方法重置输入源。
        //digest()返回值16位长度的哈希值，由byte[]承接
        byte[] md5Array = md5.digest();
        //byte[]通常我们会转化为十六进制的32位长度的字符串来使用,本文会介绍三种常用的转换方法
        return CommonByteUtil.bytesToHex(md5Array);
    }

    /**
     * 获取文件的MD5，32位
     *
     * @param file 文件
     * @return 文件的MD5
     * @throws NoSuchAlgorithmException 异常
     * @throws IOException              异常
     */
    public static String getMD5(File file) throws NoSuchAlgorithmException, IOException {
        if (file == null || !file.exists()) {
            return null;
        }
        MessageDigest md5 = MessageDigest.getInstance("MD5");
        FileInputStream fis = new FileInputStream(file);

        byte[] dataBytes = new byte[1024];
        int readLength;
        while ((readLength = fis.read(dataBytes)) != -1) {
            md5.update(dataBytes, 0, readLength);
        }
        byte[] md5Array = md5.digest();

        fis.close();

        return CommonByteUtil.bytesToHex(md5Array);
    }

    /**
     * 把图片进行Base64编码
     *
     * @param bitmap 要编码的图片
     * @return 编码结果
     * @throws IOException 文件操作错误
     */
    public static String encodeImage(Bitmap bitmap) throws IOException {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        // 读取图片到ByteArrayOutputStream
        bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos); // 参数如果为100那么就不压缩
        String base64Str = Base64.encodeToString(baos.toByteArray(), Base64.DEFAULT);
        baos.close();
        return base64Str;
    }
}
